﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DotNET4Study
{
    public static class LinqStudy2
    {
        private static List<string> fruits1 = new List<string>() { "Apple", "Pear", "Orange", "Melo", "Banana" };
        private static List<string> fruits2 = new List<string>() { "Cherry", "Banana", "Coconut" };

        public static void Execute()
        {
            IEnumerable<string> result = null;

            Console.WriteLine("以下演示Contact的使用(Contact会将两个集合中所有的元素都连接起来，即便两个集合中有重复的元素)");
            result = fruits1.Concat(fruits2);
            foreach (string enity in result)
            {
                Console.WriteLine(enity);
            }

            Console.WriteLine("以下演示Union的使用(Contact会将两个集合中所有的元素都连接起来，但是会排出第二集合中跟第一个集合中重复的元素)");
            result = fruits1.Union(fruits2);
            foreach (string enity in result)
            {
                Console.WriteLine(enity);
            }

            Console.WriteLine("以下代码演示Zip（该方法针对两个不同类执行一个最简单的联接）");
            var employees = new List<Employee>
            {  
                    new Employee { Id = 13, Name = "John Doe", Salary = 13482.50 },  
                    new Employee { Id = 42, Name = "Sue Smith", Salary = 98234.13 },  
                    new Employee { Id = 99, Name = "Jass PPe", Salary = 32421.12 }  
            };
            var seats = new List<Seat>
            {  
                    new Seat { Id = 1, Cost = 42 },  
                    new Seat { Id = 2, Cost = 42 },  
                    new Seat { Id = 3, Cost = 100 },  
                    new Seat { Id = 4, Cost = 100 },  
                    new Seat { Id = 5, Cost = 125 },  
                    new Seat { Id = 6, Cost = 125 },  
            };

            var p = employees.Zip(seats, (e, s) => { return new { EmployeeID = e.Id, SeatID = s.Id }; });
            foreach (var v in p)
            {
                Console.WriteLine("{0}-{1}", v.EmployeeID, v.SeatID);
            }

            Console.WriteLine("以下代码演示Join（该方法类似与SQL中的inner join，获取两个集合中匹配的记录，丢弃不匹配的记录）");
            var badges = new List<Badge>  
            {  
                new Badge { EmployeeId = 10, BadgeNumber = 1 },  
                new Badge { EmployeeId = 13, BadgeNumber = 2 },  
                new Badge { EmployeeId = 20, BadgeNumber = 3 },  
                new Badge { EmployeeId = 25, BadgeNumber = 4 },  
                new Badge { EmployeeId = 42, BadgeNumber = 5 },  
                new Badge { EmployeeId = 10, BadgeNumber = 6 },  
                new Badge { EmployeeId = 13, BadgeNumber = 7 },  
            };

            var m = employees.Join(badges, e => e.Id, b => b.EmployeeId, (e, b) => { return new { EName = e.Name, BNumber = b.BadgeNumber }; });
            foreach (var a in m)
            {
                Console.WriteLine("{0}--{1}", a.EName, a.BNumber);
            }

            Console.WriteLine("以下代码演示GroupJoin（该方法类）");
            var coll = employees.GroupJoin(badges, e => e.Id, b => b.EmployeeId, (e, b) => { return new { EName = e.Name, BList = b.ToList() }; });
            foreach (var c1 in coll)
            {
                Console.WriteLine(c1.EName);
                foreach (var c2 in c1.BList)
                {
                    Console.WriteLine("\t" + c2.BadgeNumber);
                }
            }

            Console.WriteLine("以下演示GroupBy");
            var r = employees.GroupBy(e => { return new { EFrist = e.Name.First() }; });
            foreach(var t in r)
            {
                foreach (var i in t)
                {
                    Console.WriteLine(i.Name);
                }
                Console.WriteLine("------");
            }
        }


        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public double Salary { get; set; }
        }

        public class Seat
        {
            public int Id { get; set; }
            public double Cost { get; set; }
        }

        public class Badge
        {
            public int EmployeeId { get; set; }
            public int BadgeNumber { get; set; }
        }
    }
}
